package com.example.mvp.fragment;

import android.app.Activity;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

import com.example.mvp.activity.BaseActivityMVP;
import com.example.mvp.binder.BaseDataBinder;
import com.example.mvp.delegate.XDelegate;

import java.lang.ref.WeakReference;

import cc.vv.lkbasecomponent.base.ui.LKBaseActivity;
import cc.vv.lkbasecomponent.base.ui.LKBaseFragment;
import cc.vv.lkbasecomponent.base.ui.loading.InterLoading;
import cc.vv.lkbasecomponent.base.ui.loading.LKBaseLoading;
import cc.vv.lkbasecomponent.http.lib.CallBack;
import cc.vv.lkbasecomponent.http.lib.wrap.LKCall;
import cc.vv.lklibrary.log.LogOperate;


/**
 * Created by sun.li on 2018/6/6.
 *
 * @author sun.li
 */

public abstract class BaseFragmentMVP<T extends XDelegate> extends Fragment {
    public BaseActivityMVP mActivity;
    /** 视图托管类对象*/
    protected T viewDelegate;
    protected boolean isVisible = true;
    protected boolean isFirst = true;
    /**
     * 控件是否初始化完成
     */
    protected boolean isPrepared = false;
    /** 公共数据视图绑定控制器对象*/
    protected BaseDataBinder binder;
    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        super.onActivityCreated(savedInstanceState);
        isPrepared = true;
        //已经显示，并且是第一次进入则加载数据
        if (isVisible && isFirst) {
            isFirst = false;
        }
    }
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        if(this.getActivity() instanceof BaseActivityMVP) {
            this.mActivity = (BaseActivityMVP)this.getActivity();
        }
        isPrepared = true;
        this.setRetainInstance(false);
        try {
            viewDelegate = getDelegateClass().newInstance();
        } catch (java.lang.InstantiationException e) {
            throw new RuntimeException("create IDelegate error");
        } catch (IllegalAccessException e) {
            throw new RuntimeException("create IDelegate error");
        }
    }

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        if (null == viewDelegate.getRootView()) {
            viewDelegate.create(inflater, container);
        }
        try {
            if(null!=viewDelegate.getRootView()){
                ViewGroup parent = (ViewGroup)viewDelegate.getRootView().getParent();
                if (null != parent) {
                    parent.removeView(viewDelegate.getRootView());
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return viewDelegate.getRootView();
    }

    @Override
    public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view,savedInstanceState);
        LogOperate.e("shif ====="+this.getUserVisibleHint());
        if(this.getUserVisibleHint()) {
            this.isVisible = true;
            this.onVisibles();
        } else {
            this.isVisible = false;
        }
    }

    @Override
    public void setUserVisibleHint(boolean isVisibleToUser) {
        super.setUserVisibleHint(isVisibleToUser);
        if(this.getUserVisibleHint()) {
            this.isVisible = true;
            this.onVisibles();
        } else {
            this.isVisible = false;
            this.onVisibles();
        }

    }

    /**
     * fragement可见时调用
     */
    protected void onVisibles() {
        if (!isPrepared || !isVisible || !isFirst) {
            return;
        }


        Bundle arguments = this.getArguments();
        this.isFirst = false;
        initData();
        binder = getDataBinder();
        initView(arguments);
        viewDelegate.initWidget();
        bindEvenListener();
    }

    protected abstract void initView(Bundle var1);
    /** 初始化界面数据*/
    protected abstract void initData();

    /** 注册界面控件点击事件*/
    protected abstract void bindEvenListener();

    /** 指定界面的视图控制器，必须指定*/
    protected abstract Class<T> getDelegateClass();

    /** 公共数据视图绑定控制器数据对象*/
    public abstract BaseDataBinder getDataBinder();

    public <D extends Object> void notifyModelChanged(D data) {
        if (binder != null) {
            binder.viewBindModel(viewDelegate, data);
        }
    }

    @Override
    public void onViewStateRestored(@Nullable Bundle savedInstanceState) {
        super.onViewStateRestored(savedInstanceState);
        if(null == viewDelegate){
            try {
                viewDelegate = getDelegateClass().newInstance();
            } catch (java.lang.InstantiationException e) {
                throw new RuntimeException("create IDelegate error");
            } catch (IllegalAccessException e) {
                throw new RuntimeException("create IDelegate error");
            }
        }
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        /* 界面关闭解除视图绑定操作*/
        viewDelegate = null;
    }


    public InterLoading getLoading() {
        return (InterLoading)(this.mActivity == null?new LKBaseLoading(cc.vv.lkbasecomponent.R.layout.view_base_loading):this.mActivity.getLoading());
    }

    protected View[] initLoadingPierceViews() {
        return null;
    }

    protected boolean initCanPierce() {
        return false;
    }

    public <T> BaseCallBack<T> defCallBack() {
        return new BaseCallBack(this);
    }

    protected void onRequestSuccess(String url, Object obj) {
    }

    protected void onRequestStart(String url, boolean isLoading) {
        if(this.mActivity != null) {
            InterLoading loading = this.mActivity.getLoading();
            if(loading != null && isLoading) {
                loading.showLoading();
            }

        }
    }

    protected void onRequestFinish(String url, int resultCode, boolean isLoading) {
        if(this.mActivity != null) {
            InterLoading loading = this.mActivity.getLoading();
            if(loading != null && isLoading) {
                loading.closeLoading();
            }

        }
    }

    protected void onRequestFailure(String url, boolean isLoading, String exceptionStr) {
    }

    protected void onRequestCancel(String url, boolean isLoading) {
    }

    public final void cancelCall(LKCall call) {
        if(call != null) {
            call.cancel();
        }

    }
    protected static class BaseCallBack<T> extends CallBack<T> {
        private WeakReference<BaseFragmentMVP> mRef;

        public BaseCallBack(BaseFragmentMVP fragment) {
            this.mRef = new WeakReference(fragment);
        }

        @Override
        public void onSuccess(String url, T obj) {
            if(this.mRef.get() != null) {
                ((BaseFragmentMVP)this.mRef.get()).onRequestSuccess(url, obj);
            }

        }

        @Override
        public void onStart(String url, boolean isLoading) {
            if(this.mRef.get() != null) {
                ((BaseFragmentMVP)this.mRef.get()).onRequestStart(url, isLoading);
            }

        }

        @Override
        public void onFailure(String url, boolean isLoading, String exceptionStr) {
            if(this.mRef.get() != null) {
                ((BaseFragmentMVP)this.mRef.get()).onRequestFailure(url, isLoading, exceptionStr);
            }

        }

        @Override
        public void onCancel(String url, boolean isLoading) {
            if(this.mRef.get() != null) {
                ((BaseFragmentMVP)this.mRef.get()).onRequestCancel(url, isLoading);
            }

        }

        @Override
        public void onFinish(String url, int resultCode, boolean isLoading) {
            if(this.mRef.get() != null) {
                ((BaseFragmentMVP)this.mRef.get()).onRequestFinish(url, resultCode, isLoading);
            }

        }

        @Override
        public void onUpLoadProgress(String filePath, int progress) {
        }

        @Override
        public void onDownLoadProgress(String url, String filePath, int progress) {
        }

        @Override
        public void onDownLoadFailure(String url, String filePath) {
        }

        @Override
        public void onDownLoadSuccess(String url, String filePath) {
        }
    }

}
